#pragma once

#include <QWidget>
#include <QVector>
#include <QStack>
#include <QStylePainter>
#include <QPixmap>

struct CmdWindowInfo
{
	QString	title; 
	QString	url;
	QString params;//same command, different parameters
	int		cmdId = 0;
	int		winId = -1;
	char	flag = 0;//{1:web, 2:fixed, 4:hide, 8:seperated}
	QRect	rect;
	QWidget* widget = nullptr;

	void setWebFlag() { flag = flag | 0x01; }
	bool isWeb() const { return (flag & 0x01) == 0x01; }
	void setFixed(bool v) 
	{ 
		if (v)
			flag = flag | 0x02;
		else
			flag = flag & 0xFD;
	}
	bool isFixed() const { return (flag & 0x02) == 0x02; }

	bool isHide() const { return (flag & 0x04) == 0x04; }
	void setHide(bool v)
	{
		if (v)
			flag = flag | 0x04;
		else
			flag = flag & 0xFB;
	}

	bool isPopup() const { return (flag & 0x08) == 0x08; }
	void setPopup(bool v)
	{
		if (v)
			flag = flag | 0x08;
		else
			flag = flag & (~0x08);
	}
};

struct LayoutInfo
{
	bool	fixedWidth = false;
	int		max_tab_width = 90;
	int		min_tab_width = 55;
	int		image_top_gap = 7;
	int		image_gag = 5; //图片两侧空白
	int		tab_image_height = 29/*31*/;
	int		tab_overlap = 0/*4*/; //标签叠加
	int		active_tab_width = max_tab_width;
	int		normal_tab_width = max_tab_width;
	int		group_gap = 0/*10*/;//固定标签组间隔
	int		right_btn_width = 18;
	int		max_fixed_tab_count = 5;
	int		close_btn_width = 12;
	int		clost_btn_gap = 5;
	bool	showMore = false;

	void applyScale(float scale)
	{
		max_tab_width = 90 * scale;
		min_tab_width = 55 * scale;
		image_top_gap = 7 * scale;
		tab_image_height = 29/*31*/ * scale;
		tab_overlap = 0/*4*/ * scale;
		active_tab_width = max_tab_width;
		group_gap = 0/*10*/ * scale;
		right_btn_width = 18 * scale;
		close_btn_width = 12 * scale;
		clost_btn_gap = 5 * scale;
	}
};

class SImageButton;
class QPropertyAnimation;
class QAction;

class TabBar : public QWidget
{
	Q_OBJECT
	Q_PROPERTY(int animateProgess READ progress WRITE setProgress)
public:
	TabBar(QWidget* parent);

	CmdWindowInfo& addTab(const QString& title, QWidget* ctrl = nullptr, int cmdId = 0, bool fixed = false);
	CmdWindowInfo* tabById(int tabId);
	int tabForCmd(int id, const QString& params);
	void activateTabByTabId(int tabId);
	void updateTabTitle(int tabId, const QString& title);
	void attachWidget(CmdWindowInfo cwi);
	int leftSpace() const;
	bool tabShrinked() const { return m_layout.normal_tab_width < m_layout.max_tab_width; }

protected:
	bool event(QEvent *event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseDoubleClickEvent(QMouseEvent* event) override;
	void mouseReleaseEvent(QMouseEvent* event) override;
	void mouseMoveEvent(QMouseEvent* event) override;
	void paintEvent(QPaintEvent* event) override;
	void resizeEvent(QResizeEvent* event) override;
	void leaveEvent(QEvent* event) override;
	void dragEnterEvent(QDragEnterEvent* event) override;
	void dragLeaveEvent(QDragLeaveEvent* event) override;
	void dragMoveEvent(QDragMoveEvent* event) override;
	void dropEvent(QDropEvent* event) override;
	void contextMenuEvent(QContextMenuEvent *event) override;

signals:
	void tabActivated(int newTabId);
	void tabClose(int tabId);
	void tabSeperated(CmdWindowInfo ti);
	void requestResize(int type);

protected slots:
	void onBtnClicked();
	void onAction();

private:
	void layoutTabs(bool reset = false);
	void drawTab(QStylePainter& painter, const CmdWindowInfo& ti, bool isActive = false, bool isHoverClose = false);
	void drawMoveBtns(QStylePainter& painter);

	void closeTab(int pos);
	void insertTab(const CmdWindowInfo& ti, int pos);
	void activateWindow(int pos);
	int hitTestTab(QPoint pos);
	int tabPosById(int id);

	void startDrag();
	void doDragMove(int tabPosX);
	
	void onMoveBtnClicked(bool left);
	bool checkLeftHide() const;
	bool checkRightHide() const;

	QPixmap	getDragPixmap() const;

	//animate
	int progress() const { return m_animateProgess; }
	void setProgress(int v);
	void stopAnimation();
	void startAnimation();

	void buildActions();
	void showMoreMenu();
	void unFixTab(int tabPos);

private:
	LayoutInfo			m_layout;
	QVector<CmdWindowInfo>	m_tabs;
	int					m_activePos = 0;
	int					m_fixedCount = 0;
	int					m_hoverPos = -1;

	SImageButton* m_btnMore = nullptr;
	SImageButton* m_btnRefresh = nullptr;
	QVector<int>		m_hideTabs;
	QRect				m_rectMoveLeft;
	QRect				m_rectMoveRight;

	bool				m_dragging= false;
	QPoint				m_startDragPos;
	QPoint				m_dragOffset;
	CmdWindowInfo				m_dragTab;

	QStack<int>			m_activeHistory;//store the tab id
	bool				m_animating = false;
	QVector<CmdWindowInfo>	m_tabsForAnimate;
	int					m_animateProgess = 0;
	QPropertyAnimation* m_animation = nullptr;

	int					m_tabMenu = -1;
	QAction*			m_actionRefresh = nullptr;
	QAction*			m_actionFix = nullptr;
	QAction*			m_actionClose = nullptr;
	QAction*			m_actionCloseOthers = nullptr;
	QAction*			m_actionCloseAll = nullptr;
	QAction*			m_actionCloseAllBonds = nullptr;
	QAction*			m_actionUnfixAll = nullptr;
	QAction* m_actionFixedTabWidth = nullptr;
	QAction* m_actionVariantTabWidth = nullptr;
};